﻿using System;
using System.Collections.Generic;
using ProjectDanmaku.Core;
using ProjectDanmaku.Scenario;
using ProjectDanmaku.Util;
using UnityEngine;

namespace ProjectDanmaku.Entity.Manipulator
{
    public class ShootableCollidePhysicsManipulator : IEntityManipulator
    {
        private uint layerMask = BitUtility.All;
        
        private float colliderRadius = CoordUtility.PixelToUnit(2);
        
        public Action<EntityData> OnHitCallback;

        public void SetLayerMask(uint mask)
        {
            layerMask = mask;
        }

        public void SetColliderRadius(float radius)
        {
            colliderRadius = radius;
        }
        
        public void Do(EntityData data)
        {
            // Check Avatar First
            if ((layerMask & 1u) > 0)
            {
                var collider = DanmakuScenario.CurrentAvatarBehavior.GetCollideCircle();
                if (new Vector2(collider.x - data.Position.x, collider.y - data.Position.y).magnitude < 
                    collider.z + colliderRadius)
                {
                    data.Active = false;
                    data.Destroyed = true;
                    
                    DanmakuScenario.CurrentAvatarBehavior.OnHit();
                    
                    return;
                }
            }
            
            ShootableObject shotObj = null;

            foreach (var shootableObject in DanmakuScenario.ShootableObjects)
            {
                var collider = shootableObject.GetCollider();
                
                if (!collider.CheckMask(layerMask))
                    return;
                
                if (new Vector2(collider.Collider.x - data.Position.x, collider.Collider.y - data.Position.y).magnitude 
                        < collider.Collider.z + colliderRadius)
                {
                    shotObj = shootableObject;
                    data.Active = false;
                    data.Destroyed = true;
                    break;
                }
            }
            
            if (shotObj)
            {
                OnHitCallback?.Invoke(data);
                shotObj.OnShot();
            }
        }
    }
}